
// 这里实现标签页的切换
function initSwitchTab() {
    // 1. 先获取到相关的元素(标签页的按钮, 会话列表, 好友列表)
    let tabSession = document.querySelector('.tab .tab-session');
    let tabFriend = document.querySelector('.tab .tab-friend');
    // querySelectorAll 可以同时选中多个元素. 得到的结果是个数组
    // [0] 就是会话列表
    // [1] 就是好友列表
    let lists = document.querySelectorAll('.list');
    // 2. 针对标签页按钮, 注册点击事件. 
 
    tabSession.onclick = function() {
        // a) 设置图标
        tabSession.style.backgroundImage = 'url(img/对话.png)';
        tabFriend.style.backgroundImage = 'url(img/用户2.png)';
        // b) 让会话列表显示出来, 让好友列表进行隐藏
        lists[0].classList = 'list';
        lists[1].classList = 'list hide';
    }

    tabFriend.onclick = function() {
        // a) 设置图标
        tabSession.style.backgroundImage = 'url(img/对话2.png)';
        tabFriend.style.backgroundImage = 'url(img/用户.png)'
        // b) 让好友列表显示, 让会话列表隐藏
        lists[0].classList = 'list hide';
        lists[1].classList = 'list';
    }
}
initSwitchTab();
// 获取用户名展示在页面左上方·，且保存id信息
function userInfo(){
    $.ajax({
        type:"get",
        url:"/userInfo",
        success: function(result){
            if(result!=null&&result.userId>0){
                let userDiv = document.querySelector(".main .left .user");
                userDiv.innerHTML = result.username;
                userDiv.setAttribute("user-id",result.userId);
    
            }else{
                alert("用户未登录");
                 location.assign('/login.html');
            }
        }
    });
  
}
userInfo();

//获取朋友列表
function getFriendList(){
    $.ajax({
        type: "get",
        url: "/friendList",
        success: function(body){
            //清空原数据
            let friendListUl = document.querySelector("#friend-list");
            friendListUl.innerHTML = "";
            //遍历js对象数组并添加到页面上
            for (let friend of body){
                let li = document.createElement('li');
                li.innerHTML = "<h4>"+ friend.friendName+"</h4>";
                li.setAttribute('friend-id',friend.friendId);
                friendListUl.append(li);

                //为好友添加点击事件
                li.onclick = function(){
                    clickfriend(friend);
                }
            } 
        },
        error: function() {
            console.log('获取好友列表失败!');
        }
    });
}
getSessionList();
getFriendList();

//获取对话列表
function getSessionList(){
    $.ajax({
        type :"get",
        url :"getSessionList",
        success :function(body){
            //1.清空原数据
            let sessionUL = document.querySelector("#session-list");
            sessionUL.innerHTML = '';
            //2.遍历js数组
            for(let session of body){
                //如果消息太长，进行截断操作
                if(session.lastMessage.length>10){
                    session.lastMessage = session.lastMessage.substring(0,10);
                }

                let li = document.createElement('li');
                li.setAttribute("message-session-id",session.sessionId);
                li.innerHTML = '<h3>'+session.friends[0].friendName+'</h3>'+
                                '<p>' + session.lastMessage + '</p>';
                sessionUL.appendChild(li);
                //为会话添加点击事件
                li.onclick = function(){
                    clicksession(li);
                }
            }
        }
    });
}


function clicksession(curli){
    //1.将选中会话变成高亮
    let lis = document.querySelectorAll("#session-list>li");

    for(let li of lis){
        if (li == curli) {
            li.className = 'selected';
        } else {
            li.className = '';
        }
    }
    // 2. 获取指定会话的历史消息
    let sessionId = curli.getAttribute("message-session-id");
    getHistoryMessage(sessionId);
}

// 这个函数负责获取指定会话的历史消息. 
function getHistoryMessage(sessionId) {
    console.log("获取历史消息 sessionId=" + sessionId);
    // 1. 先清空右侧列表中的已有内容
    let titleDiv = document.querySelector('.right .title');
    titleDiv.innerHTML = '';
    let messageShowDiv = document.querySelector('.right .message-show');
    messageShowDiv.innerHTML = '';
    // 2. 重新设置会话的标题. 新的会话标题是点击的那个会话上面显示的标题
    //    先找到当前选中的会话是哪个. 被选中的会话带有 selected 类的. 
    let selectedH3 = document.querySelector('#session-list .selected>h3');
    if (selectedH3) {
        titleDiv.innerHTML = selectedH3.innerHTML;
    }
    $.ajax({
        type: 'get',
        url: 'message?sessionId=' + sessionId,
        success: function(body) {
            for (let message of body) {
                addMessage(messageShowDiv, message);
            }
            // 加个操作: 在构造好消息列表之后, 控制滚动条, 自动滚动到最下方. 
            scrollBottom(messageShowDiv);
        }
    });
}

function addMessage(messageShowDiv, message) {
    // 使用这个 div 表示一条消息
    let messageDiv = document.createElement('div');
    // 此处需要针对当前消息是不是用户自己发的, 决定是靠左还是靠右. 
    let selfUsername = document.querySelector('.left .user').innerHTML;
    if (selfUsername == message.fromName) {
        // 消息是自己发的. 靠右
        messageDiv.className = 'message message-right';
    } else {
        // 消息是别人发的. 靠左
        messageDiv.className = 'message message-left';
    }
    messageDiv.innerHTML = '<div class="box">' 
        + '<h4>' + message.fromName + '</h4>'
        + '<p>' + message.content + '</p>'
        + '</div>';
    messageShowDiv.appendChild(messageDiv);
}

// 把 messageShowDiv 里的内容滚动到底部. 
function scrollBottom(elem) {
    // 1. 获取到可视区域的高度
    let clientHeight = elem.offsetHeight;
    // 2. 获取到内容的总高度
    let scrollHeight = elem.scrollHeight;
    // 3. 进行滚动操作, 第一个参数是水平方向滚动的尺寸. 第二个参数是垂直方向滚动的尺寸
    elem.scrollTo(0, scrollHeight - clientHeight);
}

//z这个函数用于添加friend的点击事件
function clickfriend(friend){
    
    //1.首先在会话列表里查找当前好友会话 
    let sessionli = findSessionByName(friend.friendName);
    let sessionLis = document.querySelector("#session-list");
    //如果找到对应会话，置顶，虚拟点击事件
    if(sessionli){
        sessionLis.insertBefore(sessionli,sessionLis.children[0]);
        sessionli.click();
    }else{
        //如果没找到 创建li 插入到会话列表中 注册点击事件 并告诉服务器xinxi
        sessionli = document.createElement("li");
        sessionli.innerHTML = "<h3>"+friend.friendName+"</h3>"+"<p></p>";
        sessionLis.insertBefore(sessionli,sessionLis.children[0]);
        sessionli.onclick = function(){
            clicksession(sessionli);
        }
        sessionli.click();
        //z这里传入sessionli是为了保存session-id到标签属性中
        createSession(friend.friendId,sessionli);
    }
    //切换到会话界面 虚拟点击会话图标即可。

    let tabSession = document.querySelector('.tab .tab-session');
    tabSession.click();
    

}
//z这个函数用于根据好友名字查找会话 有则返回相应会话 无则返回空
function findSessionByName(name){
    let sessionLis = document.querySelectorAll("#session-list>li");
    for(let sessionli of sessionLis){
        let h3 = sessionli.querySelector("h3");

        if(h3.innerHTML == name){
            return sessionli;
        }
    }

    return null;
}
//这个函数用于向后端发送添加会话的请求
 function createSession(friendId,sessionli){

    $.ajax({
        type:"post",
        url:"/session?toUserId="+friendId,
        success:function(body){
            console.log('请求成功');
            sessionli.setAttribute("message-session-id",body.sessionId);
        },
        error:function(){
            console.log("创建会话请求失败");
        }
    });

 }

/////////////////////////////////////////////////////
// 操作 websocket
/////////////////////////////////////////////////////

// 创建 websocket 实例
let websocket = new WebSocket("ws://127.0.0.1:8080/webSocketMessage");
//let websocket = new WebSocket("ws://" + location.host + "/WebSocketMessage");

websocket.onopen = function() {
    console.log("websocket 连接成功!");
}

websocket.onmessage = function(e) {
    console.log("websocket 收到消息! " + e.data);
    // 此时收到的 e.data 是个 json 字符串, 需要转成 js 对象
    let resp = JSON.parse(e.data);
    if (resp.type == 'message') {
        // 处理消息响应
        handleMessage(resp);
    } else {
        // resp 的 type 出错!
        console.log("resp.type 不符合要求!");
    }
}

websocket.onclose = function() {
    console.log("websocket 连接关闭!");
}

websocket.onerror = function() {
    console.log("websocket 连接异常!");
}

function handleMessage(resp) {
    // 把客户端收到的消息, 给展示出来. 
    // 展示到对应的会话预览区域, 以及右侧消息列表中. 

    // 1. 根据响应中的 sessionId 获取到当前会话对应的 li 标签. 
    //    如果 li 标签不存在, 则创建一个新的
    let curSessionLi = findSessionLi(resp.sessionId);
    if (curSessionLi == null) {
        // 就需要创建出一个新的 li 标签, 表示新会话. 
        curSessionLi = document.createElement('li');
        curSessionLi.setAttribute('message-session-id', resp.sessionId);
        // 此处 p 标签内部应该放消息的预览内容. 一会后面统一完成, 这里先置空
        curSessionLi.innerHTML = '<h3>' + resp.fromName + '</h3>'
            + '<p></p>';
        // 给这个 li 标签也加上点击事件的处理
        curSessionLi.onclick = function() {
            clicksession(curSessionLi);
        }
    }
    // 2. 把新的消息, 显示到会话的预览区域 (li 标签里的 p 标签中)
    //    如果消息太长, 就需要进行截断. 
    let p = curSessionLi.querySelector('p');
    p.innerHTML = resp.content;
    if (p.innerHTML.length > 10) {
        p.innerHTML = p.innerHTML.substring(0, 10) + '...';
    }
    // 3. 把收到消息的会话, 给放到会话列表最上面. 
    let sessionListUL = document.querySelector('#session-list');
    sessionListUL.insertBefore(curSessionLi, sessionListUL.children[0]);
    // 4. 如果当前收到消息的会话处于被选中状态, 则把当前的消息给放到右侧消息列表中. 
    //    新增消息的同时, 注意调整滚动条的位置, 保证新消息虽然在底部, 但是能够被用户直接看到. 
    if (curSessionLi.className == 'selected') {
        // 把消息列表添加一个新消息. 
        let messageShowDiv = document.querySelector('.right .message-show');
        addMessage(messageShowDiv, resp);
        scrollBottom(messageShowDiv);
    }
    // 其他操作, 还可以在会话窗口上给个提示 (红色的数字, 有几条消息未读), 还可以播放个提示音.  
    // 这些操作都是纯前端的. 实现也不难, 不是咱们的重点工作. 暂时不做了. 
}

function findSessionLi(targetSessionId) {
    // 获取到所有的会话列表中的 li 标签
    let sessionLis = document.querySelectorAll('#session-list li');
    for (let li of sessionLis) {
        let sessionId = li.getAttribute('message-session-id');
        if (sessionId == targetSessionId) {
            return li;
        }
    }
    // 啥时候会触发这个操作, 就比如如果当前新的用户直接给当前用户发送消息, 此时没存在现成的 li 标签
    return null;
}
   function initSendButton() {
    // 获取到发送按钮 和 消息输入框
    let sendButton = document.querySelector('.right .ctrl button');
    let messageInput = document.querySelector('.right .message-input');
    // 给发送按钮注册一个点击事件
    sendButton.onclick = function() {
        // 先针对输入框的内容做个简单判定. 比如输入框内容为空, 则啥都不干
        if (!messageInput.value) {
            // value 的值是 null 或者 '' 都会触发这个条件
            return;
        }
        // 获取当前选中的 li 标签的 sessionId
        let selectedLi = document.querySelector('#session-list .selected');
        if (selectedLi == null) {
            return;
        }
        let sessionId = selectedLi.getAttribute('message-session-id');
        // 构造 json 数据
        let req = {
            type: 'message',
            sessionId: sessionId,
            content: messageInput.value
        };
        req = JSON.stringify(req);
        console.log("[websocket] send: " + req);
        // 通过 websocket 发送消息
        websocket.send(req);
        // 发送完成之后, 清空之前的输入框
        messageInput.value = '';
    }
}

initSendButton();
